#!/usr/bin/env node
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const cors = require('cors');
const bodyParser = require('body-parser');
const path = require('path');
const { createLogger } = require('./utils/logger');
const { ensureDir } = require('./utils/fileHelper');

// 创建日志记录器
const logger = createLogger('server');

// 创建Express应用
const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
  cors: {
    origin: '*',
    methods: ['GET', 'POST']
  }
});

// 配置中间件
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 静态文件服务
app.use(express.static(path.join(__dirname, 'public')));

// 确保必要目录存在
ensureDir(path.join(__dirname, 'config'));
ensureDir(path.join(__dirname, 'logs'));

// 设置API路由
app.use('/api/storage', require('./api/storage'));
app.use('/api/build', require('./api/build'));
app.use('/api/deploy', require('./api/deploy'));
app.use('/api/config', require('./api/config'));

// 设置WebSocket命名空间
const buildNamespace = io.of('/build');
const deployNamespace = io.of('/deploy');

// 将命名空间添加到app对象，以便API路由可以访问
app.set('buildNamespace', buildNamespace);
app.set('deployNamespace', deployNamespace);

// 处理WebSocket连接 - 构建命名空间
buildNamespace.on('connection', (socket) => {
  const socketId = String(socket.id);
  logger.info(`Build client connected: ${socketId}`);
  
  // 加入构建任务房间
  socket.on('joinBuildRoom', (buildId) => {
    if (!buildId) {
      logger.warn(`Client ${socketId} tried to join build room without buildId`);
      return;
    }
    
    socket.join(buildId);
    logger.info(`Client ${socketId} joined build room ${buildId}`);
    
    // 发送确认消息
    socket.emit('roomJoined', { 
      buildId, 
      message: `已加入构建任务 ${buildId}` 
    });
  });
  
  // 离开构建任务房间
  socket.on('leaveBuildRoom', (buildId) => {
    if (!buildId) return;
    
    socket.leave(buildId);
    logger.info(`Client ${socketId} left build room ${buildId}`);
  });
  
  // 断开连接
  socket.on('disconnect', () => {
    logger.info(`Build client disconnected: ${socketId}`);
  });
});

// 处理WebSocket连接 - 部署命名空间
deployNamespace.on('connection', (socket) => {
  const socketId = String(socket.id);
  logger.info(`Deploy client connected: ${socketId}`);
  
  // 加入部署任务房间
  socket.on('joinDeployRoom', (deployId) => {
    if (!deployId) {
      logger.warn(`Client ${socketId} tried to join deploy room without deployId`);
      return;
    }
    
    socket.join(deployId);
    logger.info(`Client ${socketId} joined deploy room ${deployId}`);
    
    // 发送确认消息
    socket.emit('roomJoined', { 
      deployId, 
      message: `已加入部署任务 ${deployId}` 
    });
  });
  
  // 离开部署任务房间
  socket.on('leaveDeployRoom', (deployId) => {
    if (!deployId) return;
    
    socket.leave(deployId);
    logger.info(`Client ${socketId} left deploy room ${deployId}`);
  });
  
  // 断开连接
  socket.on('disconnect', () => {
    logger.info(`Deploy client disconnected: ${socketId}`);
  });
});

// 设置404处理
app.use((req, res) => {
  res.status(404).json({
    code: 404,
    message: '接口不存在'
  });
});

// 设置错误处理
app.use((err, req, res, next) => {
  logger.error('服务器错误:', err);
  res.status(500).json({
    code: 500,
    message: '服务器内部错误',
    error: err.message
  });
});

// 设置端口
const PORT = process.env.PORT || 3101;

// 导出app以供其他模块使用
module.exports = { app, server };

// 如果直接运行此文件，则启动服务器
if (require.main === module) {
  server.listen(PORT, () => {
    logger.info(`部署服务器已启动，监听端口 ${PORT}`);
    console.log(`部署服务器已启动，监听端口 ${PORT}`);
  });
} 